package com.jfinal.plugin.activerecord;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

public class NamedDb {

	private static NamedParameterDbPro namedParameterDbPro = NamedParameterDbPro.use();

	public static NamedParameterDbPro use(String configName) {
		return NamedParameterDbPro.use(configName);
	}

	public static <T> List<T> query(Config config, Connection conn, String namedSql, Map<String, Object> paraMap)
			throws SQLException {
		return namedParameterDbPro.query(config, conn, namedSql, paraMap);
	}

	/**
	 * @see #query(String, String, Map<String,Object>)
	 */
	public static <T> List<T> query(String namedSql, Map<String, Object> paraMap) {
		return namedParameterDbPro.query(namedSql, paraMap);
	}

	/**
	 * Execute sql query and return the first result. I recommend add "limit 1" in your sql.
	 * @param sql an SQL statement that may contain one or more '?' IN parameter placeholders
	 * @param paras the parameters of sql
	 * @return Map<String, Object> if your sql has select more than one column,
	 * 			and it return Object if your sql has select only one column.
	 */
	public static <T> T queryFirst(String namedSql, Map<String, Object> paraMap) {
		return namedParameterDbPro.queryFirst(namedSql, paraMap);
	}

	// 26 queryXxx method below -----------------------------------------------
	/**
	 * Execute sql query just return one column.
	 * @param <T> the type of the column that in your sql's select statement
	 * @param sql an SQL statement that may contain one or more '?' IN parameter placeholders
	 * @param paras the parameters of sql
	 * @return List<T>
	 */
	public static <T> T queryColumn(String namedSql, Map<String, Object> paraMap) {
		return namedParameterDbPro.queryColumn(namedSql, paraMap);
	}

	public static String queryStr(String namedSql, Map<String, Object> paraMap) {
		return (String) namedParameterDbPro.queryStr(namedSql, paraMap);
	}

	public static Integer queryInt(String namedSql, Map<String, Object> paraMap) {
		return (Integer) namedParameterDbPro.queryInt(namedSql, paraMap);
	}

	public static Long queryLong(String namedSql, Map<String, Object> paraMap) {
		return (Long) namedParameterDbPro.queryLong(namedSql, paraMap);
	}

	public static Double queryDouble(String namedSql, Map<String, Object> paraMap) {
		return (Double) namedParameterDbPro.queryDouble(namedSql, paraMap);
	}

	public static Float queryFloat(String namedSql, Map<String, Object> paraMap) {
		return (Float) namedParameterDbPro.queryFloat(namedSql, paraMap);
	}

	public static java.math.BigDecimal queryBigDecimal(String namedSql, Map<String, Object> paraMap) {
		return (java.math.BigDecimal) namedParameterDbPro.queryBigDecimal(namedSql, paraMap);
	}

	public static byte[] queryBytes(String namedSql, Map<String, Object> paraMap) {
		return (byte[]) namedParameterDbPro.queryBytes(namedSql, paraMap);
	}

	public static java.util.Date queryDate(String namedSql, Map<String, Object> paraMap) {
		return (java.util.Date) namedParameterDbPro.queryDate(namedSql, paraMap);
	}

	public static java.sql.Time queryTime(String namedSql, Map<String, Object> paraMap) {
		return (java.sql.Time) namedParameterDbPro.queryTime(namedSql, paraMap);
	}

	public static java.sql.Timestamp queryTimestamp(String namedSql, Map<String, Object> paraMap) {
		return (java.sql.Timestamp) namedParameterDbPro.queryTimestamp(namedSql, paraMap);
	}

	public static Boolean queryBoolean(String namedSql, Map<String, Object> paraMap) {
		return (Boolean) namedParameterDbPro.queryBoolean(namedSql, paraMap);
	}

	public static Number queryNumber(String namedSql, Map<String, Object> paraMap) {
		return (Number) namedParameterDbPro.queryNumber(namedSql, paraMap);
	}

	// 26 queryXxx method under -----------------------------------------------

	/**
	 * Execute sql update
	 */
	public static int update(Config config, Connection conn, String namedSql, Map<String, Object> paraMap) throws SQLException {
		return namedParameterDbPro.update(config, conn, namedSql, paraMap);
	}

	/**
	 * Execute update, insert or delete sql statement.
	 * @param sql an SQL statement that may contain one or more '?' IN parameter placeholders
	 * @param paras the parameters of sql
	 * @return either the row count for <code>INSERT</code>, <code>UPDATE</code>,
	 *         or <code>DELETE</code> statements, or 0 for SQL statements 
	 *         that return nothing
	 */
	public static int update(String namedSql, Map<String, Object> paraMap) {
		return namedParameterDbPro.update(namedSql, paraMap);
	}

	public static List<Record> find(Config config, Connection conn, String namedSql, Map<String, Object> paraMap)
			throws SQLException {
		return namedParameterDbPro.find(config, conn, namedSql, paraMap);
	}

	/**
	 * @see #find(String, String, Map<String, Object>)
	 */
	public static List<Record> find(String namedSql, Map<String, Object> paraMap) {
		return namedParameterDbPro.find(namedSql, paraMap);
	}

	/**
	 * Find first record. I recommend add "limit 1" in your sql.
	 * @param sql an SQL statement that may contain one or more '?' IN parameter placeholders
	 * @param paras the parameters of sql
	 * @return the Record object
	 */
	public static Record findFirst(String namedSql, Map<String, Object> paraMap) {
		return namedParameterDbPro.findFirst(namedSql, paraMap);
	}

	public static Page<Record> paginate(Config config, Connection conn, int pageNumber, int pageSize, String select,
			String sqlExceptSelect, Map<String, Object> paraMap) throws SQLException {
		return namedParameterDbPro.paginate(config, conn, pageNumber, pageSize, select, sqlExceptSelect, paraMap);
	}

	/**
	 * @see #paginate(String, int, int, String, String, Map<String, Object>)
	 */
	public static Page<Record> paginate(int pageNumber, int pageSize, String select, String sqlExceptSelect,
			Map<String, Object> paraMap) {
		return namedParameterDbPro.paginate(pageNumber, pageSize, select, sqlExceptSelect, paraMap);
	}

	/**
	 * @see #paginate(String, int, int, String, String)
	 */
	public static Page<Record> paginate(int pageNumber, int pageSize, String select, String sqlExceptSelect) {
		return namedParameterDbPro.paginate(pageNumber, pageSize, select, sqlExceptSelect);
	}

	/**
	 * Find Record by cache.
	 * @see #find(String, Object...)
	 * @param cacheName the cache name
	 * @param key the key used to get date from cache
	 * @return the list of Record
	 */
	public static List<Record> findByCache(String cacheName, Object key, String sql, Map<String, Object> paraMap) {
		return namedParameterDbPro.findByCache(cacheName, key, sql, paraMap);
	}

	/**
	 * @see #findByCache(String, Object, String, Object...)
	 */
	public static List<Record> findByCache(String cacheName, Object key, String sql) {
		return namedParameterDbPro.findByCache(cacheName, key, sql);
	}

	/**
	 * Paginate by cache.
	 * @see #paginate(int, int, String, String, Object...)
	 * @return Page
	 */
	public static Page<Record> paginateByCache(String cacheName, Object key, int pageNumber, int pageSize, String select,
			String sqlExceptSelect, Map<String, Object> paraMap) {
		return namedParameterDbPro.paginateByCache(cacheName, key, pageNumber, pageSize, select, sqlExceptSelect, paraMap);
	}

	/**
	 * @see #paginateByCache(String, Object, int, int, String, String, Object...)
	 */
	public static Page<Record> paginateByCache(String cacheName, Object key, int pageNumber, int pageSize, String select,
			String sqlExceptSelect) {
		return namedParameterDbPro.paginateByCache(cacheName, key, pageNumber, pageSize, select, sqlExceptSelect);
	}
}
